package it.tukano.collections;

import java.io.File;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * A logger-based persistent map
 */
public class PersistentMap<K extends Serializable, T extends Serializable> implements Map<K, T> {

    private Map<K, T> map;
    private PersistentMapLogger<K, T> logger;
    
    public PersistentMap(String filePath) {
        this(new PersistentMapLogger<K, T>(new File(filePath)));
    }

    public PersistentMap(File file) {
        this(new PersistentMapLogger<K, T>(file));
    }

    public PersistentMap(PersistentMapLogger<K, T> logger) {
        this.logger = logger;
        this.map = logger.readLog();
    }

    public int size() {
        return map.size();
    }

    public boolean isEmpty() {
        return map.isEmpty();
    }

    public boolean containsKey(Object key) {
        return map.containsKey(key);
    }

    public boolean containsValue(Object value) {
        return map.containsValue(value);
    }

    public T get(Object key) {
        return map.get(key);
    }

    public T put(K key, T value) {
        logger.put(key, value);
        return map.put(key, value);
    }

    public T remove(Object key) {
        logger.remove(key);
        return map.remove(key);
    }

    public void putAll(Map<? extends K, ? extends T> m) {
        logger.putAll(m);
        map.putAll(m);
    }

    public void clear() {
        logger.clear();
        map.clear();
    }

    public Set<K> keySet() {
        return map.keySet();
    }

    public Collection<T> values() {
        return map.values();
    }

    public Set<Entry<K, T>> entrySet() {
        return map.entrySet();
    }

    public void waitForEnd() {
        logger.waitForEnd();
    }
    
    public void close(boolean waitForEnd) {
        try {
            if(waitForEnd) {
                logger.waitForEnd();
            }
        } finally {
            logger.dispose();
        }
    }
}
